#pragma once

#include <atomic>
#include <random>
#include <string>
#include "protocol/routeinfo.pb.h"
#include "protocol/transport.pb.h"
#include "base/Logger.h"

namespace zeroplus::mq::consumer
{

    enum LoadBalanceStrategy : uint8_t
    {
        ROUND_ROBIN,
        RANDOM,
        HASH
    };

    class RouteInfoSelector
    {
    private:
        std::atomic<int> index_; // 轮询索引

    public:
        RouteInfoSelector();
        ~RouteInfoSelector();

        std::tuple<routeinfo::QueueData, routeinfo::BrokerData, bool> SelectRouteInfo(const routeinfo::TopicRouteInfo &topicRouteInfo,
                                                                                      LoadBalanceStrategy strategy, std::string messageKey = "");

    private:
        std::tuple<routeinfo::BrokerData, bool> SelectBroker(const routeinfo::TopicRouteInfo &topicRouteInfo, const std::string &brokerName);
        std::tuple<routeinfo::QueueData, bool> SelectQueue(const routeinfo::TopicRouteInfo &topicRouteInfo, LoadBalanceStrategy strategy, std::string messageKey);
        std::tuple<routeinfo::QueueData, bool> SelectQueueByRoundRobin(const routeinfo::TopicRouteInfo &topicRouteInfo);
        std::tuple<routeinfo::QueueData, bool> SelectQueueByRandom(const routeinfo::TopicRouteInfo &topicRouteInfo);
        std::tuple<routeinfo::QueueData, bool> SelectQueueByHash(const routeinfo::TopicRouteInfo &topicRouteInfo, std::string &messageKey);
    };
}
